`include "chunjun_define.sv" 
`include "chunjun_lib_define.sv" 

//================================================================================================
// File Name   : chunjun_dcu_utag_way.sv
// Create Time : Mon Jan  6 14:36:32 2025
// Description :
// 
//  Micro-tag way: comprises N entries for each way, each entry only has address tag and 
//  valid flag.
//
//================================================================================================
 

 module chunjun_dcu_utag_way #(
  parameter UTAG_ENT_N        = 2,
  parameter UTAG_TAG_W        = 26,
  // DO NOT MODIFY DERIVATIVE PARAMETER
  parameter UTAG_IDX_W        = $clog2(UTAG_ENT_N)
  )(
 
input  logic                            clk     ,
input  logic                            rst_n   ,

// Load1 check interface
input  logic                            ld1_vld_m1 ,
input  logic [31:5]                     ld1_addr_m1,
output logic                            ld1_hit_m1 ,

// Update interface
 
input  logic [UTAG_ENT_N-1:0]           hit_updt_m2,
input  logic [UTAG_TAG_W-1:0]           hit_tag_m2 ,
 
input  logic [UTAG_ENT_N-1:0]           lfl_updt_m1,
input  logic [UTAG_TAG_W-1:0]           lfl_tag_m1 ,
 
input  logic [UTAG_ENT_N-1:0]           inv_updt_m1
 
);

//=================================================================================
// Local Parameters
//=================================================================================

//=================================================================================
// Local Variables 
//=================================================================================
 
logic [UTAG_ENT_N-1:0]                  dff_utag_updt_en;
logic [UTAG_ENT_N-1:0]                  dff_utag_vld_d ;
logic [UTAG_ENT_N-1:0]                  dff_utag_vld_q ;
logic [UTAG_ENT_N-1:0][UTAG_TAG_W-1:0]  dff_utag_tag_d ;
logic [UTAG_ENT_N-1:0][UTAG_TAG_W-1:0]  dff_utag_tag_q ;

logic [UTAG_ENT_N-1:0]                  utag_cmp;

//=================================================================================
// Update Each Entry
//=================================================================================
 

for (genvar i=0; i<UTAG_ENT_N; i++) begin : g_utag_entry
 
  assign dff_utag_updt_en[i] = hit_updt_m2[i] | lfl_updt_m1[i] | inv_updt_m1[i];

  assign dff_utag_vld_d[i] = inv_updt_m1[i] ? 1'b0 : 1'b1;

  assign dff_utag_tag_d[i] = inv_updt_m1[i] ? {UTAG_TAG_W{1'b0}} :
                             lfl_updt_m1[i] ? lfl_tag_m1         :
                                              hit_tag_m2         ;

  `WDFFER(dff_utag_vld_q[i], dff_utag_vld_d[i], dff_utag_updt_en[i], clk, rst_n)
  `WDFFER(dff_utag_tag_q[i], dff_utag_tag_d[i], dff_utag_updt_en[i], clk, rst_n)
          
  assign utag_cmp[i] = dff_utag_vld_q[i] & (ld1_addr_m1[5+:UTAG_IDX_W] == i) & 
                       (ld1_addr_m1[31-:UTAG_TAG_W] == dff_utag_tag_q[i]);
 
end

assign ld1_hit_m1 = ld1_vld_m1 & (|utag_cmp);
 
//=================================================================================
// Assertion
//=================================================================================


endmodule
`include "chunjun_undefine.sv" 
